// source --> https://juttersloep.nl/wp-content/plugins/recras/js/onlinebooking.min.js?ver=1.10.3 "use strict"; function _objectValues(obj) { var values = []; var keys = Object.keys(obj); for (var k = 0; k < keys.length; k++) values.push(obj[keys[k]]); return values; } function _objectEntries(obj) { var entries = []; var keys = Object.keys(obj); for (var k = 0; k < keys.length; k++) entries.push([keys[k], obj[keys[k]]]); return entries; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /******************************* * Recras integration library * * v 1.10.3 * *******************************/ var RecrasBooking = /*#__PURE__*/function () { function RecrasBooking() { var _this = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, RecrasBooking); this.datePicker = null; this.PAYMENT_DIRECT = 'mollie'; this.PAYMENT_AFTERWARDS = 'factuur'; this.RECRAS_INFINITY = 99999; // This is used instead of "true infinity" because JSON doesn't have infinity this.languageHelper = new RecrasLanguageHelper(); if (!(options instanceof RecrasOptions)) { throw new Error(this.languageHelper.translate('ERR_OPTIONS_INVALID')); } this.options = options; this.eventHelper = new RecrasEventHelper(); this.eventHelper.setAnalytics(this.options.getAnalytics()); this.eventHelper.setEvents(this.options.getAnalyticsEvents()); var optionsPromise = this.languageHelper.setOptions(options); this.element = this.options.getElement(); this.element.classList.add('recras-onlinebooking'); this.fetchJson = function (url) { return RecrasHttpHelper.fetchJson(url, _this.error); }; this.postJson = function (url, data) { return RecrasHttpHelper.postJson(_this.options.getApiBase() + url, data, _this.error.bind(_this)); }; if (this.options.getLocale()) { if (!RecrasLanguageHelper.isValid(this.options.getLocale())) { console.warn(this.languageHelper.translate('ERR_INVALID_LOCALE', { LOCALES: RecrasLanguageHelper.validLocales.join(', ') })); } else { this.languageHelper.setLocale(this.options.getLocale()); } } if (this.options.getPreFilledAmounts()) { if (!this.options.isSinglePackage()) { console.warn(this.languageHelper.translate('ERR_AMOUNTS_NO_PACKAGE')); } } if (this.options.getPreFilledDate()) { this.prefillDateIfPossible(); } if (this.options.getPreFilledTime()) { this.prefillTimeIfPossible(); } RecrasCSSHelper.loadCSS('global'); RecrasCSSHelper.loadCSS('booking'); RecrasCSSHelper.loadCSS('pikaday'); this.clearAll(); this.loadingIndicatorShow(this.element); this.promise = optionsPromise.then(function () { return RecrasCalendarHelper.loadScript(); }).then(function () { return _this.getTexts(); }).then(function (texts) { _this.texts = texts; return _this.getPackages(); }).then(function (packages) { _this.loadingIndicatorHide(); var pck = _this.options.getPackageId(); if (_this.options.isSinglePackage()) { if (Array.isArray(pck)) { pck = pck[0]; } return _this.changePackage(pck); } else if (Array.isArray(pck) && pck.length > 1) { packages = packages.filter(function (p) { return pck.includes(p.id); }); } return _this.showPackages(packages); }); } _createClass(RecrasBooking, [{ key: "prefillDateIfPossible", value: function prefillDateIfPossible() { var date = new Date(this.options.getPreFilledDate()); if (isNaN(date.getTime())) { console.warn(this.languageHelper.translate('ERR_INVALID_DATE')); return false; } if (date < new Date()) { console.warn(this.languageHelper.translate('ERR_DATE_PAST')); return false; } if (!this.options.isSinglePackage()) { console.warn(this.languageHelper.translate('ERR_DATE_NO_SINGLE_PACKAGE')); return false; } this.prefilledDate = date; return true; } }, { key: "prefillTimeIfPossible", value: function prefillTimeIfPossible() { var time = this.options.getPreFilledTime(); if (!time.match(/^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$/)) { console.warn(this.languageHelper.translate('ERR_INVALID_TIME')); return false; } this.prefilledTime = time; return true; } }, { key: "hasAtLeastOneProduct", value: function hasAtLeastOneProduct(pack) { if (this.shouldShowBookingSize(pack) && this.bookingSize() > 0) { return true; } var hasAtLeastOneProduct = false; for (var _i2 = 0, _this$getLinesNoBooki2 = this.getLinesNoBookingSize(pack); _i2 < _this$getLinesNoBooki2.length; _i2++) { var line = _this$getLinesNoBooki2[_i2]; var lineEl = this.findElement("[data-package-id=\"".concat(line.id, "\"]")); if (lineEl && lineEl.value > 0) { hasAtLeastOneProduct = true; } } return hasAtLeastOneProduct; } }, { key: "amountsValid", value: function amountsValid(pack) { for (var _i4 = 0, _this$getLinesNoBooki4 = this.getLinesNoBookingSize(pack); _i4 < _this$getLinesNoBooki4.length; _i4++) { var line = _this$getLinesNoBooki4[_i4]; var lineEl = this.findElement("[data-package-id=\"".concat(line.id, "\"]")); if (!lineEl) { console.warn("Element for line ".concat(line.id, " not found")); return false; } var aantal = lineEl.value; if (aantal > 0 && aantal < line.aantal_personen) { return false; } if (aantal > 0 && line.min && aantal < line.min) { return false; } if (line.max && aantal > line.max) { return false; } } if (this.shouldShowBookingSize(pack) && this.bookingSize() > 0) { if (this.bookingSize() < this.bookingSizeMinimum(pack) || this.bookingSize() > this.bookingSizeMaximum(pack)) { return false; } } return this.hasAtLeastOneProduct(pack); } }, { key: "appendHtml", value: function appendHtml(msg) { this.element.insertAdjacentHTML('beforeend', msg); } }, { key: "applyVoucher", value: function applyVoucher(packageID, voucherCode) { var _this2 = this; if (!voucherCode) { this.setDiscountStatus(this.languageHelper.translate('VOUCHER_EMPTY')); return Promise.resolve(false); } if (this.appliedVouchers[voucherCode]) { this.setDiscountStatus(this.languageHelper.translate('VOUCHER_ALREADY_APPLIED')); return Promise.resolve(false); } if (!this.selectedDate) { this.setDiscountStatus(this.languageHelper.translate('DATE_INVALID')); return Promise.resolve(false); } return this.postJson('onlineboeking/controleervoucher', { arrangement_id: packageID, datum: RecrasDateHelper.datePartOnly(this.selectedDate), producten: this.productCounts(), vouchers: [voucherCode] }).then(function (json) { var result = json[voucherCode]; if (!result.valid) { return Promise.resolve(false); } _this2.appliedVouchers[voucherCode] = result.processed; _this2.showTotalPrice(); return true; }); } }, { key: "recheckDiscountCode", value: function recheckDiscountCode() { var _this3 = this; this.checkDiscountcode(this.selectedPackage.id, RecrasDateHelper.datePartOnly(this.selectedDate), this.discount.code).then(function (status) { if (status) { _this3.setDiscountStatus(_this3.languageHelper.translate('DISCOUNT_APPLIED'), false); } else { _this3.discount = null; _this3.showTotalPrice(); var statusEl = _this3.findElement('.discount-status'); if (statusEl) { statusEl.parentNode.removeChild(statusEl); } } }); } }, { key: "recheckVouchers", value: function recheckVouchers() { var voucherCodes = Object.keys(this.appliedVouchers); this.appliedVouchers = []; var promises = []; for (var _i6 = 0; _i6 < voucherCodes.length; _i6++) { var voucherCode = voucherCodes[_i6]; promises.push(this.applyVoucher(this.selectedPackage.id, voucherCode)); } return Promise.all(promises); } }, { key: "bookingSize", value: function bookingSize() { var bookingSizeEl = this.findElement('.bookingsize'); if (!bookingSizeEl) { return 0; } var bookingSizeValue = parseInt(bookingSizeEl.value, 10); if (isNaN(bookingSizeValue)) { return 0; } return bookingSizeValue; } }, { key: "bookingSizeLines", value: function bookingSizeLines(pack) { return pack.regels.filter(function (line) { return line.onlineboeking_aantalbepalingsmethode === 'boekingsgrootte'; }); } }, { key: "bookingSizeMaximum", value: function bookingSizeMaximum(pack) { var lines = this.bookingSizeLines(pack).filter(function (line) { return line.max; }); if (lines.length === 0) { return this.RECRAS_INFINITY; } var maxes = lines.map(function (line) { return line.max; }); return Math.min.apply(Math, _toConsumableArray(maxes)); } }, { key: "bookingSizeLineMinimum", value: function bookingSizeLineMinimum(line) { if (line.min) { return line.min; } if (line.onlineboeking_aantalbepalingsmethode === 'vast') { return 0; } return line.product.minimum_aantal; } }, { key: "bookingSizeMinimum", value: function bookingSizeMinimum(pack) { var _this4 = this; var minSize = 0; this.bookingSizeLines(pack).forEach(function (line) { minSize = Math.max(minSize, _this4.bookingSizeLineMinimum(line)); }); return minSize; } }, { key: "amountFromPersons", value: function amountFromPersons(product, persons) { return persons; //TODO: this doesn't work yet because public product API does not send: // aantalbepaling, aantal, per_x_personen_afronding, per_x_personen if (product.aantalbepaling === 'vast') { return product.aantal; } var fn = product.per_x_personen_afronding === 'beneden' ? Math.floor : Math.ceil; return product.aantal * fn(persons / product.per_x_personen); } }, { key: "bookingSizePrice", value: function bookingSizePrice(pack) { var _this5 = this; var nrOfPersons = Math.max(pack.aantal_personen, 1); var price = 0; var lines = this.bookingSizeLines(pack); lines.forEach(function (line) { price += Math.max(_this5.amountFromPersons(line.product, nrOfPersons), line.product.minimum_aantal) * parseFloat(line.product.verkoop); }); return price / nrOfPersons; } }, { key: "filterPackagesFromoptions", value: function filterPackagesFromoptions(packages) { var pck = this.options.getPackageId(); if (!Array.isArray(pck)) { return packages; } return packages.filter(function (p) { return pck.includes(p.id); }); } }, { key: "changePackage", value: function changePackage(packageID) { var _this6 = this; var selectedPackage = this.packages.filter(function (p) { return p.id === packageID; }); this.appliedVouchers = {}; this.discount = null; if (selectedPackage.length === 0) { // Reset form this.selectedPackage = null; this.clearAll(); var packages = this.filterPackagesFromoptions(this.packages); this.showPackages(packages); this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_RESET); return Promise.resolve(false); } else { this.clearAllExceptPackageSelection(); this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_PACKAGE_CHANGED, selectedPackage[0].arrangement, selectedPackage[0].id); } this.selectedPackage = selectedPackage[0]; return this.showProducts(this.selectedPackage).then(function () { _this6.nextSectionActive('.recras-package-select', '.recras-amountsform'); _this6.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_PRODUCTS_SHOWN); if (_this6.options.getAutoScroll() === true) { var scrollOptions = { behavior: 'smooth' }; if (!('scrollBehavior' in document.documentElement.style)) { scrollOptions = true; } _this6.findElement('.recras-amountsform').scrollIntoView(scrollOptions); } _this6.checkDependencies(); _this6.loadingIndicatorShow(_this6.findElement('.recras-amountsform')); return _this6.showDateTimeSelection(_this6.selectedPackage); }).then(function () { _this6.loadingIndicatorHide(); _this6.showContactForm(_this6.selectedPackage); }); } }, { key: "checkBookingSize", value: function checkBookingSize(pack) { if (!this.shouldShowBookingSize(pack)) { return; } var bookingSize = this.bookingSize(); var bsMaximum = this.bookingSizeMaximum(pack); var bsMinimum = this.bookingSizeMinimum(pack); if (bookingSize < bsMinimum) { this.setMinMaxAmountWarning('bookingsize', bsMinimum, 'minimum'); } else if (bookingSize > bsMaximum) { this.setMinMaxAmountWarning('bookingsize', bsMaximum, 'maximum'); } this.maybeDisableBookButton(); } }, { key: "checkDependencies", value: function checkDependencies() { var _this7 = this; _toConsumableArray(this.findElements('.recras-product-dependency')).forEach(function (el) { el.parentNode.removeChild(el); }); _toConsumableArray(this.findElements('[data-package-id]')).forEach(function (el) { el.classList.remove('recras-input-invalid'); }); this.requiresProduct = false; this.productCounts().forEach(function (line) { if (line.aantal > 0) { var packageLineID = line.arrangementsregel_id; var product = _this7.findProduct(packageLineID).product; var thisProductRequiresProduct = false; if (!product.vereist_product) { console.warn('You are logged in to this particular Recras. Because of API differences between logged-in and logged-out state, required products do not work as expected.'); } else { product.vereist_product.forEach(function (vp) { if (!_this7.dependencySatisfied(line.aantal, vp)) { thisProductRequiresProduct = true; _this7.requiresProduct = true; var requiredAmount = _this7.requiredAmount(line.aantal, vp); var requiredProductName = _this7.getProductByID(vp.vereist_product_id).weergavenaam; var message = _this7.languageHelper.translate('PRODUCT_REQUIRED', { NUM: line.aantal, PRODUCT: product.weergavenaam, REQUIRED_AMOUNT: requiredAmount, REQUIRED_PRODUCT: requiredProductName }); _this7.findElement('.recras-amountsform').insertAdjacentHTML('beforeend', "".concat(message, "")); } }); } if (thisProductRequiresProduct) { var productInput = _this7.findElement("[data-package-id=\"".concat(packageLineID, "\"]")); productInput.classList.add('recras-input-invalid'); } } }); this.maybeDisableBookButton(); } }, { key: "checkDiscountAndVoucher", value: function checkDiscountAndVoucher() { var _this8 = this; var discountPromise = this.checkDiscountcode(this.selectedPackage.id, RecrasDateHelper.datePartOnly(this.selectedDate), this.findElement('#discountcode').value.trim()); var voucherPromise = this.applyVoucher(this.selectedPackage.id, this.findElement('#discountcode').value.trim()); Promise.all([discountPromise, voucherPromise]).then(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), discountStatus = _ref2[0], voucherStatus = _ref2[1]; if (discountStatus || voucherStatus) { var status; if (discountStatus) { status = 'DISCOUNT_APPLIED'; } else { status = 'VOUCHER_APPLIED'; } _this8.setDiscountStatus(_this8.languageHelper.translate(status), false); _this8.findElement('#discountcode').value = ''; _this8.nextSectionActive('.recras-discounts', '.recras-contactform'); } else { _this8.setDiscountStatus(_this8.languageHelper.translate('DISCOUNT_INVALID')); } }); } }, { key: "checkDiscountcode", value: function checkDiscountcode(packageID, date, code) { var _this9 = this; return this.fetchJson(this.options.getApiBase() + 'onlineboeking/controleerkortingscode' + '?datum=' + date + '&arrangement=' + packageID + '&kortingscode=' + encodeURIComponent(code)).then(function (discount) { if (discount === false) { return false; } discount.code = code; _this9.discount = discount; _this9.showTotalPrice(); return true; }); } }, { key: "checkMaximumForPackage", value: function checkMaximumForPackage() { var _this10 = this; var maxPerLine = this.selectedPackage.maximum_aantal_personen_online; if (maxPerLine === null) { return Promise.resolve(null); } var showWarning = false; var selectedProducts = this.productCounts(); return this.languageHelper.filterTags(this.texts.maximum_aantal_online_boeking_overschreden, this.selectedPackage ? this.selectedPackage.id : null).then(function (msg) { selectedProducts.forEach(function (p) { if (p.aantal > maxPerLine && !showWarning) { var input = _this10.findElement("[data-package-id=\"".concat(p.arrangementsregel_id, "\"]")); if (!input) { input = _this10.findElement('#bookingsize'); } if (input) { var warningEl = document.createElement('div'); warningEl.classList.add('maximum-amount'); warningEl.classList.add('recras-full-width'); warningEl.innerHTML = msg; input.parentNode.parentNode.insertBefore(warningEl, input.parentNode.nextSibling); input.classList.add('recras-input-invalid'); } else { _this10.findElement('.recras-amountsform').insertAdjacentHTML('beforeend', "".concat(msg, "")); } showWarning = true; } }); }); } }, { key: "contactFormValid", value: function contactFormValid() { var contactFormIsValid = this.findElement('.recras-contactform').checkValidity(); var contactFormRequiredCheckboxes = this.contactForm.checkRequiredCheckboxes(); return contactFormIsValid && contactFormRequiredCheckboxes; } }, { key: "setMinMaxAmountWarning", value: function setMinMaxAmountWarning(lineID, minAmount) { var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'minimum'; var warnEl = document.createElement('span'); warnEl.classList.add(type + '-amount'); var lineEl = this.findElement("#".concat(lineID)); if (!lineEl) { console.warn("Element for line ".concat(lineID, " not found")); return false; } lineEl.classList.add('recras-input-invalid'); var text; if (type === 'minimum') { text = this.languageHelper.translate('PRODUCT_MINIMUM', { MINIMUM: minAmount }); } else { text = this.languageHelper.translate('PRODUCT_MAXIMUM', { MAXIMUM: minAmount }); } warnEl.innerHTML = text; var label = this.findElement("label[for=\"".concat(lineID, "\"]")); label.parentNode.appendChild(warnEl); } }, { key: "checkMinMaxAmounts", value: function checkMinMaxAmounts() { for (var _i8 = 0, _this$productCounts2 = this.productCounts(); _i8 < _this$productCounts2.length; _i8++) { var product = _this$productCounts2[_i8]; if (product.aantal < 1) { continue; } var packageLineID = product.arrangementsregel_id; var packageLine = this.findProduct(packageLineID); var input = this.findElement("[data-package-id=\"".concat(packageLineID, "\"]")); if (!input) { // This is a "booking size" line - this is handled in checkBookingSize continue; } if (product.aantal < packageLine.product.minimum_aantal) { this.setMinMaxAmountWarning(input.id, packageLine.product.minimum_aantal, 'minimum'); } else if (product.aantal < packageLine.aantal_personen) { this.setMinMaxAmountWarning(input.id, packageLine.aantal_personen, 'minimum'); } else if (packageLine.min !== undefined && product.aantal < packageLine.min) { this.setMinMaxAmountWarning(input.id, packageLine.min, 'minimum'); } else if (packageLine.max !== null && product.aantal > packageLine.max) { this.setMinMaxAmountWarning(input.id, packageLine.max, 'maximum'); } } } }, { key: "clearAll", value: function clearAll() { this.clearElements(this.element.children); } }, { key: "clearAllExceptPackageSelection", value: function clearAllExceptPackageSelection() { var packageSelect = this.findElement('.recras-package-select'); if (packageSelect) { packageSelect.classList.remove('recras-completed'); packageSelect.classList.add('recras-active'); } var elements = document.querySelectorAll('#' + this.element.id + ' > *:not(.recras-package-select)'); this.clearElements(elements); } }, { key: "clearElements", value: function clearElements(elements) { if (this.datePicker) { this.datePicker.destroy(); } this.availableDays = []; _toConsumableArray(elements).forEach(function (el) { el.parentNode.removeChild(el); }); this.maybeAddLatestErrorElement(); } }, { key: "dependencySatisfied", value: function dependencySatisfied(hasNow, requiredProduct) { for (var _i10 = 0, _this$productCounts4 = this.productCounts(); _i10 < _this$productCounts4.length; _i10++) { var line = _this$productCounts4[_i10]; if (line.aantal === 0) { continue; } var product = this.findProduct(line.arrangementsregel_id).product; if (product.id !== parseInt(requiredProduct.vereist_product_id, 10)) { continue; } var requiredAmount = this.requiredAmount(hasNow, requiredProduct); return line.aantal >= requiredAmount; } return false; } }, { key: "error", value: function error(msg) { this.loadingIndicatorHide(); var bookingErrorsEl = this.findElement('#bookingErrors'); if (bookingErrorsEl) { bookingErrorsEl.parentNode.appendChild(this.findElement('.latestError')); } this.maybeAddLatestErrorElement(); this.findElement('.latestError').innerHTML = "".concat(this.languageHelper.translate('ERR_GENERAL'), "
").concat(msg, "
"); } }, { key: "findElement", value: function findElement(querystring) { return this.element.querySelector(querystring); } }, { key: "findElements", value: function findElements(querystring) { return this.element.querySelectorAll(querystring); } }, { key: "findProduct", value: function findProduct(packageLineID) { return this.selectedPackage.regels.filter(function (line) { return line.id === packageLineID; })[0]; } }, { key: "formatPrice", value: function formatPrice(price) { return this.languageHelper.formatPrice(price); } }, { key: "getAvailableDays", value: function getAvailableDays(packageID, begin, end) { var _this11 = this; var postData = { arrangement_id: packageID, begin: RecrasDateHelper.datePartOnly(begin), eind: RecrasDateHelper.datePartOnly(end), producten: this.productCountsNoBookingSize() }; if (this.shouldShowBookingSize(this.selectedPackage)) { postData.boekingsgrootte = this.bookingSize(); } return this.postJson('onlineboeking/beschikbaredagen', postData).then(function (json) { _this11.availableDays = _this11.availableDays.concat(json); return _this11.availableDays; }); } }, { key: "getAvailableTimes", value: function getAvailableTimes(packageID, date) { var _this12 = this; return this.postJson('onlineboeking/beschikbaretijden', { arrangement_id: packageID, datum: RecrasDateHelper.datePartOnly(date), producten: this.productCounts() }).then(function (json) { _this12.availableTimes = json; return _this12.availableTimes; }); } }, { key: "getContactForm", value: function getContactForm(pack) { var _this13 = this; this.options.setOption('form_id', pack.onlineboeking_contactformulier_id); var contactForm = new RecrasContactForm(this.options); return contactForm.getContactFormFields().then(function () { _this13.contactForm = contactForm; return contactForm; }); } }, { key: "getDiscountPrice", value: function getDiscountPrice(discount) { if (!discount) { return 0; } return discount.percentage / 100 * this.getSubTotal() * -1; } }, { key: "getLinesBookingSize", value: function getLinesBookingSize(pack) { return pack.regels.filter(function (line) { return line.onlineboeking_aantalbepalingsmethode === 'boekingsgrootte'; }); } }, { key: "getLinesNoBookingSize", value: function getLinesNoBookingSize(pack) { return pack.regels.filter(function (line) { return line.onlineboeking_aantalbepalingsmethode !== 'boekingsgrootte'; }); } }, { key: "getPackages", value: function getPackages() { var _this14 = this; return this.fetchJson(this.options.getApiBase() + 'arrangementen').then(function (json) { _this14.packages = json; return _this14.packages; }); } }, { key: "getProductByID", value: function getProductByID(id) { var products = this.selectedPackage.regels.map(function (r) { return r.product; }); return products.filter(function (p) { return p.id === id; })[0]; } }, { key: "getSubTotal", value: function getSubTotal() { var _this15 = this; var total = 0; this.productCounts().forEach(function (line) { var product = _this15.findProduct(line.arrangementsregel_id).product; var aantal = line.aantal; if (isNaN(aantal)) { aantal = 0; } total += aantal * parseFloat(product.verkoop); }); return total; } }, { key: "getSetting", value: function getSetting(settingName) { return this.fetchJson(this.options.getApiBase() + 'instellingen/' + settingName); } }, { key: "getTexts", value: function getTexts() { var settings = ['maximum_aantal_online_boeking_overschreden', 'online_boeking_betaalkeuze', 'online_boeking_betaalkeuze_achteraf_titel', 'online_boeking_betaalkeuze_ideal_titel', 'online_boeking_step0_text_pre', 'online_boeking_step0_text_post', 'online_boeking_step1_text_pre', 'online_boeking_step1_text_post', 'online_boeking_step3_text_post']; var promises = []; for (var _i12 = 0; _i12 < settings.length; _i12++) { var setting = settings[_i12]; promises.push(this.getSetting(setting)); } return Promise.all(promises).then(function (settings) { var texts = {}; settings.forEach(function (setting) { texts[setting.slug] = setting.waarde; }); return texts; }); } }, { key: "getTotalPrice", value: function getTotalPrice() { var total = this.getSubTotal(); total += this.getDiscountPrice(this.discount); total += this.getVouchersPrice(); return total; } }, { key: "getVouchersPrice", value: function getVouchersPrice() { var voucherPrice = 0; _objectValues(this.appliedVouchers).forEach(function (voucher) { _objectValues(voucher).forEach(function (line) { voucherPrice -= line.aantal * line.prijs_per_stuk; }); }); return voucherPrice; } }, { key: "loadingIndicatorHide", value: function loadingIndicatorHide() { _toConsumableArray(document.querySelectorAll('.recrasLoadingIndicator')).forEach(function (el) { el.parentNode.removeChild(el); }); } }, { key: "loadingIndicatorShow", value: function loadingIndicatorShow(afterEl) { if (!afterEl) { return; } afterEl.insertAdjacentHTML('beforeend', "".concat(this.languageHelper.translate('LOADING'), "")); } }, { key: "maybeAddLatestErrorElement", value: function maybeAddLatestErrorElement() { var errorEl = this.findElement('.latestError'); if (!errorEl) { this.appendHtml(""); } } }, { key: "maybeDisableBookButton", value: function maybeDisableBookButton() { var _this16 = this; var button = this.findElement('.bookPackage'); if (!button) { return false; } var bookingDisabledReasons = []; if (this.requiresProduct) { bookingDisabledReasons.push('BOOKING_DISABLED_REQUIRED_PRODUCT'); } if (!this.amountsValid(this.selectedPackage)) { bookingDisabledReasons.push('BOOKING_DISABLED_AMOUNTS_INVALID'); } if (!this.selectedDate) { bookingDisabledReasons.push('BOOKING_DISABLED_INVALID_DATE'); } if (!this.selectedTime) { bookingDisabledReasons.push('BOOKING_DISABLED_INVALID_TIME'); } if (!this.contactFormValid()) { bookingDisabledReasons.push('BOOKING_DISABLED_CONTACT_FORM_INVALID'); } var agreeEl = this.findElement('#recrasAgreeToAttachments'); if (agreeEl && !agreeEl.checked) { bookingDisabledReasons.push('BOOKING_DISABLED_AGREEMENT'); } if (bookingDisabledReasons.length > 0) { var reasonsList = bookingDisabledReasons.map(function (reason) { return _this16.languageHelper.translate(reason); }).join('".concat(msgs[0], "
"); paymentText += "".concat(textPostBooking, "
\n \n ").concat(paymentText, "\n \n \n".concat(json.message, "
")); } else { console.log(json); } _this28.loadingIndicatorHide(); _this28.findElement('.bookPackage').removeAttribute('disabled'); }); } }, { key: "toggleDateField", value: function toggleDateField(showHide) { var dateEl = this.findElement('#recras-onlinebooking-date'); var labelEl = this.findElement('[for="recras-onlinebooking-date"]'); if (showHide === 'hide') { dateEl.classList.add('recrasHidden'); labelEl.classList.add('recrasHidden'); } else { dateEl.classList.remove('recrasHidden'); labelEl.classList.remove('recrasHidden'); this.findElement('.recras-datetime').classList.remove('recrasHidden'); } } }, { key: "toggleTimeField", value: function toggleTimeField(showHide) { var timeEl = this.findElement('#recras-onlinebooking-time'); var labelEl = this.findElement('[for="recras-onlinebooking-time"]'); if (showHide === 'hide') { timeEl.classList.add('recrasHidden'); labelEl.classList.add('recrasHidden'); } else { timeEl.classList.remove('recrasHidden'); labelEl.classList.remove('recrasHidden'); this.findElement('.recras-datetime').classList.remove('recrasHidden'); } } }, { key: "updateProductAmounts", value: function updateProductAmounts() { var _this29 = this; this.loadingIndicatorHide(); this.availableDays = []; this.removeWarnings(); this.checkDependencies(); this.checkMinMaxAmounts(); var maxPromise = this.checkMaximumForPackage(); this.checkBookingSize(this.selectedPackage); this.recheckVouchers().then(function () { _this29.showTotalPrice(); }); this.showStandardAttachments(); var datePickerEl = this.findElement('.recras-onlinebooking-date'); var thisClass = this; maxPromise.then(function () { var amountErrors = thisClass.findElements('.minimum-amount, .maximum-amount, .recras-product-dependency'); if (amountErrors.length > 0) { thisClass.nextSectionActive(null, '.recras-amountsform'); datePickerEl.setAttribute('disabled', 'disabled'); return; } thisClass.nextSectionActive('.recras-amountsform', '.recras-datetime'); if (!thisClass.hasAtLeastOneProduct(thisClass.selectedPackage)) { return; } thisClass.loadingIndicatorShow(thisClass.findElement('label[for="recras-onlinebooking-date"]')); var startDate = new Date(); var endDate = new Date(); endDate.setMonth(endDate.getMonth() + 3); if (!thisClass.prefilledDate) { thisClass.getAvailableDaysInPeriod(thisClass.selectedPackage.id, startDate, endDate); return; } var date = thisClass.prefilledDate; startDate = new Date(date); endDate = new Date(date); endDate.setDate(endDate.getDate() + 1); thisClass.getAvailableDays(thisClass.selectedPackage.id, startDate, endDate).then(function (availableDays) { if (availableDays.includes(RecrasDateHelper.datePartOnly(date))) { thisClass.toggleDateField('hide'); thisClass.calendarOnDateSelect(date, thisClass.selectedPackage.id); } else { thisClass.toggleDateField('show'); thisClass.getAvailableDaysInPeriod(thisClass.selectedPackage.id, startDate, endDate); } }); }); } }, { key: "getAvailableDaysInPeriod", value: function getAvailableDaysInPeriod(packageId, startDate, endDate) { var _this30 = this; var datePickerEl = this.findElement('.recras-onlinebooking-date'); this.getAvailableDays(packageId, startDate, endDate).then(function (availableDays) { _this30.loadingIndicatorHide(); if (datePickerEl.value && availableDays.indexOf(datePickerEl.value) === -1) { datePickerEl.value = ''; _this30.clearTimes(); } else { datePickerEl.removeAttribute('disabled'); } }); } }, { key: "updateProductPrice", value: function updateProductPrice(el) { var priceEl = el.parentNode.querySelector('.recras-price'); var amount = parseInt(el.value, 10); if (isNaN(amount)) { amount = 0; } if (amount > 0) { priceEl.classList.remove('recrasUnitPrice'); } else { priceEl.classList.add('recrasUnitPrice'); } amount = Math.max(amount, 1); priceEl.innerHTML = this.formatPrice(amount * el.dataset.price); } }, { key: "validPaymentMethod", value: function validPaymentMethod(pack, method) { return this.paymentMethods(pack).indexOf(method) > -1; } }]); return RecrasBooking; }(); var RecrasCalendarHelper = /*#__PURE__*/function () { function RecrasCalendarHelper() { _classCallCheck(this, RecrasCalendarHelper); } _createClass(RecrasCalendarHelper, null, [{ key: "defaultOptions", value: function defaultOptions() { return { firstDay: 1, // Monday minDate: new Date(), numberOfMonths: 2, reposition: false, position: 'bottom right', toString: function toString(date) { return RecrasDateHelper.toString(date); } }; } }, { key: "i18n", value: function i18n(languageHelper) { return { previousMonth: languageHelper.translate('DATE_PICKER_PREVIOUS_MONTH'), nextMonth: languageHelper.translate('DATE_PICKER_NEXT_MONTH'), months: [languageHelper.translate('DATE_PICKER_MONTH_JANUARY'), languageHelper.translate('DATE_PICKER_MONTH_FEBRUARY'), languageHelper.translate('DATE_PICKER_MONTH_MARCH'), languageHelper.translate('DATE_PICKER_MONTH_APRIL'), languageHelper.translate('DATE_PICKER_MONTH_MAY'), languageHelper.translate('DATE_PICKER_MONTH_JUNE'), languageHelper.translate('DATE_PICKER_MONTH_JULY'), languageHelper.translate('DATE_PICKER_MONTH_AUGUST'), languageHelper.translate('DATE_PICKER_MONTH_SEPTEMBER'), languageHelper.translate('DATE_PICKER_MONTH_OCTOBER'), languageHelper.translate('DATE_PICKER_MONTH_NOVEMBER'), languageHelper.translate('DATE_PICKER_MONTH_DECEMBER')], weekdays: [languageHelper.translate('DATE_PICKER_DAY_SUNDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_MONDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_TUESDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_WEDNESDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_THURSDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_FRIDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_SATURDAY_LONG')], weekdaysShort: [languageHelper.translate('DATE_PICKER_DAY_SUNDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_MONDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_TUESDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_WEDNESDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_THURSDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_FRIDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_SATURDAY_SHORT')] }; } }, { key: "loadScript", value: function loadScript() { return new Promise(function (resolve, reject) { var scriptID = 'recrasPikaday'; // Only load script once if (document.getElementById(scriptID)) { resolve(true); } var script = document.createElement('script'); script.id = scriptID; script.src = 'https://cdnjs.cloudflare.com/ajax/libs/pikaday/1.8.2/pikaday.min.js'; script.addEventListener('load', function () { return resolve(script); }, false); script.addEventListener('error', function () { return reject(script); }, false); document.head.appendChild(script); }); } }]); return RecrasCalendarHelper; }(); var RecrasContactForm = /*#__PURE__*/function () { function RecrasContactForm() { var _this31 = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, RecrasContactForm); this.languageHelper = new RecrasLanguageHelper(); if (!(options instanceof RecrasOptions)) { throw new Error(this.languageHelper.translate('ERR_OPTIONS_INVALID')); } this.options = options; if (!this.options.getFormId()) { throw new Error(this.languageHelper.translate('ERR_NO_FORM')); } this.checkboxEventListeners = []; this.eventHelper = new RecrasEventHelper(); this.eventHelper.setEvents(this.options.getAnalyticsEvents()); this.element = this.options.getElement(); this.element.classList.add('recras-contactform-wrapper'); this.languageHelper.setOptions(options); if (RecrasLanguageHelper.isValid(this.options.getLocale())) { this.languageHelper.setLocale(this.options.getLocale()); } this.fetchJson = function (url) { return RecrasHttpHelper.fetchJson(url, _this31.error.bind(_this31)); }; this.postJson = function (url, data) { return RecrasHttpHelper.postJson(_this31.options.getApiBase() + url, data, _this31.error.bind(_this31)); }; RecrasCSSHelper.loadCSS('global'); this.GENDERS = { onbekend: 'GENDER_UNKNOWN', man: 'GENDER_MALE', vrouw: 'GENDER_FEMALE' }; // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#inappropriate-for-the-control this.AUTOCOMPLETE_OPTIONS = { 'contact.naam': 'organization', 'contact.website': 'url', 'contactpersoon.achternaam': 'family-name', 'contactpersoon.adres': 'address-line1', 'contactpersoon.plaats': 'address-level2', 'contactpersoon.postcode': 'postal-code', 'contactpersoon.voornaam': 'given-name' }; } _createClass(RecrasContactForm, [{ key: "checkRequiredCheckboxes", value: function checkRequiredCheckboxes() { var _this32 = this; this.removeWarnings(); var isOkay = true; _toConsumableArray(this.findElements('.checkboxGroupRequired')).forEach(function (group) { var checked = group.querySelectorAll('input:checked'); if (checked.length === 0) { group.parentNode.querySelector('label').insertAdjacentHTML('beforeend', "".concat(_this38.languageHelper.translate('CONTACT_FORM_SUBMIT_SUCCESS'), "
")); submitButton.parentNode.reset(); } } else { _this38.error(_this38.languageHelper.translate('CONTACT_FORM_SUBMIT_FAILED')); } submitButton.removeAttribute('disabled'); _this38.loadingIndicatorHide(); }); return false; } }]); return RecrasContactForm; }(); var RecrasCSSHelper = /*#__PURE__*/function () { function RecrasCSSHelper() { _classCallCheck(this, RecrasCSSHelper); } _createClass(RecrasCSSHelper, null, [{ key: "cssBooking", value: function cssBooking() { return "\n.recras-onlinebooking {\n max-width: 800px;\n}\n.recras-onlinebooking > form + form, .recras-finalise {\n border-top: 2px solid #dedede; /* Any love for Kirby out there? */\n}\n.recras-amountsform > div {\n display: -ms-grid;\n display: grid;\n -ms-grid-columns: 1fr 5em 7em;\n grid-template-columns: 1fr 5em 7em;\n}\n.recras-amountsform > div > div:first-child {\n -ms-grid-column: 1;\n}\n.recras-amountsform > div > input {\n -ms-grid-column: 2;\n}\n.recras-amountsform input {\n width: auto; /* Firefox fix */\n}\n.recras-amountsform > div > div:last-child {\n -ms-grid-column: 3;\n}\n.recras-input-invalid {\n border: 1px solid hsl(0, 50%, 50%);\n}\n.booking-error, .minimum-amount {\n color: hsl(0, 50%, 50%);\n}\n.recras-success {\n color: hsl(120, 40%, 40%);\n}\n.minimum-amount {\n padding-left: 0.5em;\n}\n.recras-datetime {\n display: -ms-grid;\n display: grid;\n -ms-grid-columns: 30% 70%;\n grid-template-columns: 30% 70%;\n}\n.recras-datetime > * {\n margin: 0.25em 0;\n}\n.recras-datetime label {\n display: block;\n -ms-grid-column: 1;\n}\n.recras-datetime input, .recras-datetime select {\n max-width: 12em;\n -ms-grid-column: 2;\n}\n.recras-datetime > :nth-child(-n + 2) {\n -ms-grid-row: 1;\n}\n.recras-datetime > :nth-last-child(-n + 2) {\n -ms-grid-row: 2;\n}\n.time-preview {\n padding-right: 0.5em;\n}\n.recrasUnitPrice {\n opacity: 0.5;\n}\n.recras-onlinebooking .recrasHidden {\n display: none;\n}\n"; } }, { key: "cssGlobal", value: function cssGlobal() { return "\n.latestError, .recrasError {\n color: hsl(0, 50%, 50%);\n}\n.recras-onlinebooking > *:not(.latestError):not(.recrasLoadingIndicator) {\n padding: 1em 0;\n}\n.recras-datetime, .recras-discounts > div, .recras-contactform > div {\n display: -ms-grid;\n display: grid;\n -ms-grid-columns: 1fr 12em;\n grid-template-columns: 1fr 12em;\n}\n.recras-contactform > div {\n padding-bottom: 0.25em;\n padding-top: 0.25em;\n}\n.recras-contactform label {\n display: block;\n}\n.recras-contactform > div > :last-child {\n -ms-grid-column: 2;\n}\n.recras-amountsform .recras-full-width {\n display: block;\n}\n.recras-discounts > div > input {\n -ms-grid-column: 2;\n}\n\n.recrasLoadingIndicator {\n animation: recrasSpinner 1.1s infinite linear;\n border: 0.2em solid rgba(0, 0, 0, 0.2);\n border-left-color: rgba(0, 0, 0, 0.5);\n border-radius: 50%;\n display: inline-block;\n height: 2em;\n overflow: hidden;\n text-indent: -100vw;\n width: 2em;\n}\n@keyframes recrasSpinner {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\nbutton .recrasLoadingIndicator, label .recrasLoadingIndicator {\n height: 1em;\n vertical-align: middle;\n width: 1em;\n}\nbutton .recrasLoadingIndicator {\n margin-left: 0.5em;\n}\n.bookPackage, .submitForm, .buyTemplate {\n font: inherit;\n font-weight: bold;\n padding: 0.5em 2em;\n}\n@media (max-width: 520px) {\n .pika-single {\n max-width: 256px; /* Single month is 240px + 2x8px margin */\n }\n}\n"; } }, { key: "insertIntoHead", value: function insertIntoHead(el) { document.head.insertAdjacentElement('afterbegin', el); } }, { key: "loadInlineCss", value: function loadInlineCss(cssName, inlineCss) { var styleEl = document.createElement('style'); styleEl.id = 'recras-css-' + cssName; styleEl.innerHTML = inlineCss; RecrasCSSHelper.insertIntoHead(styleEl); } }, { key: "loadExternalCss", value: function loadExternalCss(cssName, url) { var linkEl = document.createElement('link'); linkEl.id = 'recras-css-' + cssName; linkEl.setAttribute('rel', 'stylesheet'); linkEl.setAttribute('type', 'text/css'); linkEl.setAttribute('href', url); RecrasCSSHelper.insertIntoHead(linkEl); } }, { key: "loadCSS", value: function loadCSS(cssName) { var inlineCss; var url; switch (cssName) { case 'booking': inlineCss = this.cssBooking(); break; case 'global': inlineCss = this.cssGlobal(); break; case 'pikaday': url = 'https://cdnjs.cloudflare.com/ajax/libs/pikaday/1.8.2/css/pikaday.min.css'; break; default: console.warn('Unknown CSS'); break; } if (document.getElementById('recras-css-' + cssName)) { return; } if (inlineCss) { RecrasCSSHelper.loadInlineCss(cssName, inlineCss); } if (url) { RecrasCSSHelper.loadExternalCss(cssName, url); } } }]); return RecrasCSSHelper; }(); var RecrasDateHelper = /*#__PURE__*/function () { function RecrasDateHelper() { _classCallCheck(this, RecrasDateHelper); } _createClass(RecrasDateHelper, null, [{ key: "clone", value: function clone(date) { return new Date(date.getTime()); } }, { key: "datePartOnly", value: function datePartOnly(date) { var x = new Date(date.getTime() - date.getTimezoneOffset() * 60 * 1000); // Fix off-by-1 errors return x.toISOString().substr(0, 10); // Format as 2018-03-13 } }, { key: "formatStringForAPI", value: function formatStringForAPI(date) { // Handle DD-MM-YYYY pattern in code var datePatternDMY = '(0[1-9]|1[0-9]|2[0-9]|3[01])-(0[1-9]|1[012])-([0-9]{4})'; var dmyMatches = date.match(datePatternDMY); if (dmyMatches) { return dmyMatches[3] + '-' + dmyMatches[2] + '-' + dmyMatches[1]; } // Let API handle the rest. That way, the user will get an error if the input is invalid return date; } }, { key: "setTimeForDate", value: function setTimeForDate(date, timeStr) { date.setHours(timeStr.substr(0, 2), timeStr.substr(3, 2)); return date; } }, { key: "timePartOnly", value: function timePartOnly(date) { return date.toTimeString().substr(0, 5); // Format at 09:00 } }, { key: "toString", value: function toString(date) { var x = new Date(date.getTime() - date.getTimezoneOffset() * 60 * 1000); // Fix off-by-1 errors x = x.toISOString(); return x.substr(8, 2) + '-' + x.substr(5, 2) + '-' + x.substr(0, 4); } }]); return RecrasDateHelper; }(); var RecrasEventHelper = /*#__PURE__*/function () { function RecrasEventHelper() { _classCallCheck(this, RecrasEventHelper); this.analyticsEnabled = false; this.eventsEnabled = RecrasEventHelper.allEvents(); } _createClass(RecrasEventHelper, [{ key: "eventEnabled", value: function eventEnabled(name) { return this.eventsEnabled.includes(name); } }, { key: "sendEvent", value: function sendEvent(cat, action) { var label = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; var value = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined; var event; try { event = new Event(RecrasEventHelper.PREFIX_GLOBAL + ':' + cat + ':' + action); } catch (e) { // IE event = document.createEvent('Event'); event.initEvent(action, true, true); } if (this.analyticsEnabled && this.eventEnabled(action)) { if (typeof window.gtag === 'function') { // Global Site Tag - the more modern variant var eventData = { event_category: RecrasEventHelper.PREFIX_GLOBAL + ':' + cat }; if (label) { eventData.event_label = label; } if (value) { eventData.value = value; } window.gtag('event', action, eventData); } else if (typeof window.ga === 'function') { // "Old" Google Analytics var _eventData = { hitType: 'event', eventCategory: RecrasEventHelper.PREFIX_GLOBAL + ':' + cat, eventAction: action }; if (label) { _eventData.eventLabel = label; } if (value) { _eventData.eventValue = value; } // Google Analytics via Google Tag Manager doesn't work without a prefix window.ga(function () { var prefix = window.ga.getAll()[0].get('name'); if (prefix) { prefix += '.'; } window.ga(prefix + 'send', _eventData); }); } } return document.dispatchEvent(event); } }, { key: "setAnalytics", value: function setAnalytics(bool) { this.analyticsEnabled = bool; } }, { key: "setEvents", value: function setEvents(events) { this.eventsEnabled = events; } }], [{ key: "allEvents", value: function allEvents() { return [RecrasEventHelper.EVENT_BOOKING_BOOKING_SUBMITTED, RecrasEventHelper.EVENT_BOOKING_CONTACT_FORM_SHOWN, RecrasEventHelper.EVENT_BOOKING_DATE_SELECTED, RecrasEventHelper.EVENT_BOOKING_PACKAGE_CHANGED, RecrasEventHelper.EVENT_BOOKING_PACKAGES_SHOWN, RecrasEventHelper.EVENT_BOOKING_PRODUCTS_SHOWN, RecrasEventHelper.EVENT_BOOKING_REDIRECT_PAYMENT, RecrasEventHelper.EVENT_BOOKING_RESET, RecrasEventHelper.EVENT_BOOKING_TIME_SELECTED, RecrasEventHelper.EVENT_CONTACT_FORM_SUBMIT, RecrasEventHelper.EVENT_VOUCHER_REDIRECT_PAYMENT, RecrasEventHelper.EVENT_VOUCHER_TEMPLATE_CHANGED, RecrasEventHelper.EVENT_VOUCHER_VOUCHER_SUBMITTED]; } }]); return RecrasEventHelper; }(); _defineProperty(RecrasEventHelper, "PREFIX_GLOBAL", 'Recras'); _defineProperty(RecrasEventHelper, "PREFIX_BOOKING", 'Booking'); _defineProperty(RecrasEventHelper, "PREFIX_CONTACT_FORM", 'ContactForm'); _defineProperty(RecrasEventHelper, "PREFIX_VOUCHER", 'Voucher'); _defineProperty(RecrasEventHelper, "EVENT_BOOKING_BOOKING_SUBMITTED", 'BuyInProgress'); _defineProperty(RecrasEventHelper, "EVENT_BOOKING_CONTACT_FORM_SHOWN", 'ContactFormShown'); _defineProperty(RecrasEventHelper, "EVENT_BOOKING_DATE_SELECTED", 'DateSelected'); _defineProperty(RecrasEventHelper, "EVENT_BOOKING_PACKAGE_CHANGED", 'PackageChanged'); _defineProperty(RecrasEventHelper, "EVENT_BOOKING_PACKAGES_SHOWN", 'PackagesShown'); _defineProperty(RecrasEventHelper, "EVENT_BOOKING_PRODUCTS_SHOWN", 'ProductsShown'); _defineProperty(RecrasEventHelper, "EVENT_BOOKING_REDIRECT_PAYMENT", 'RedirectToPayment'); _defineProperty(RecrasEventHelper, "EVENT_BOOKING_RESET", 'Reset'); _defineProperty(RecrasEventHelper, "EVENT_BOOKING_TIME_SELECTED", 'TimeSelected'); _defineProperty(RecrasEventHelper, "EVENT_CONTACT_FORM_SUBMIT", 'Submit'); _defineProperty(RecrasEventHelper, "EVENT_VOUCHER_REDIRECT_PAYMENT", 'RedirectToPayment'); _defineProperty(RecrasEventHelper, "EVENT_VOUCHER_TEMPLATE_CHANGED", 'TemplateChanged'); _defineProperty(RecrasEventHelper, "EVENT_VOUCHER_VOUCHER_SUBMITTED", 'BuyInProgress'); var RecrasHttpHelper = /*#__PURE__*/function () { function RecrasHttpHelper() { _classCallCheck(this, RecrasHttpHelper); } _createClass(RecrasHttpHelper, null, [{ key: "call", value: function call(url, data, errorHandler) { if (!url) { throw new Error('ERR_FETCH_WITHOUT_URL'); //TODO: translate } var lastResponse; return fetch(url, data).then(function (response) { lastResponse = response; return response.json(); }).then(function (json) { if (!lastResponse.ok) { var errorMsg = json.error && json.error.message ? json.error.message : lastResponse.status + ' ' + lastResponse.statusText; errorHandler(errorMsg); return false; } return json; })["catch"](function (err) { errorHandler(err); }); } }, { key: "fetchJson", value: function fetchJson(url, errorHandler) { return this.call(url, { credentials: 'omit', method: 'get' }, errorHandler); } }, { key: "postJson", value: function postJson(url, data, errorHandler) { return this.call(url, { body: JSON.stringify(data), credentials: 'omit', method: 'post' }, errorHandler); } }]); return RecrasHttpHelper; }(); var RecrasLanguageHelper = /*#__PURE__*/function () { function RecrasLanguageHelper() { _classCallCheck(this, RecrasLanguageHelper); this.defaultLocale = 'nl_NL'; this.locale = this.defaultLocale; this.options = null; //TODO: what is the best way to handle multiple locales? this.i18n = { de_DE: { AGREE_ATTACHMENTS: 'Ich stimme den folgenden Unterlagen zu:', ATTR_REQUIRED: 'Erforderlich', BOOKING_DISABLED_AGREEMENT: 'Sie haben den Bedingungen noch nicht zugestimmt', BOOKING_DISABLED_AMOUNTS_INVALID: 'Programmbeträge sind ungültig', BOOKING_DISABLED_CONTACT_FORM_INVALID: 'Das Kontaktformular ist nicht korrekt ausgefüllt', BOOKING_DISABLED_INVALID_DATE: 'Kein Datum ausgewählt', BOOKING_DISABLED_INVALID_TIME: 'Keine Zeit ausgewählt', BOOKING_DISABLED_REQUIRED_PRODUCT: 'Erforderliches Produkt noch nicht ausgewählt', BUTTON_BOOK_NOW: 'Jetzt buchen', BUTTON_BUY_NOW: 'Jetzt kaufen', BUTTON_SUBMIT_CONTACT_FORM: 'Senden', CONTACT_FORM_CHECKBOX_REQUIRED: 'Es muss mindestens eine Option aktiviert sein', CONTACT_FORM_FIELD_INVALID: '"{FIELD_NAME}" ist ungültig', CONTACT_FORM_FIELD_REQUIRED: '"{FIELD_NAME}" ist ein erforderliches Feld', CONTACT_FORM_SUBMIT_FAILED: 'Das Kontaktformular konnte nicht gesendet werden. Bitte versuchen Sie es später noch einmal.', CONTACT_FORM_SUBMIT_SUCCESS: 'Das Kontaktformular wurde erfolgreich gesendet.', DATE: 'Datum', DATE_FORMAT: 'TT-MM-JJJJ', DATE_INVALID: 'Ungültiges datum', DATE_PICKER_NEXT_MONTH: 'Nächsten Monat', DATE_PICKER_PREVIOUS_MONTH: 'Vorheriger Monat', DATE_PICKER_MONTH_JANUARY: 'Januar', DATE_PICKER_MONTH_FEBRUARY: 'Februar', DATE_PICKER_MONTH_MARCH: 'März', DATE_PICKER_MONTH_APRIL: 'April', DATE_PICKER_MONTH_MAY: 'Mai', DATE_PICKER_MONTH_JUNE: 'Juni', DATE_PICKER_MONTH_JULY: 'Juli', DATE_PICKER_MONTH_AUGUST: 'August', DATE_PICKER_MONTH_SEPTEMBER: 'September', DATE_PICKER_MONTH_OCTOBER: 'Oktober', DATE_PICKER_MONTH_NOVEMBER: 'November', DATE_PICKER_MONTH_DECEMBER: 'Dezember', DATE_PICKER_DAY_MONDAY_LONG: 'Montag', DATE_PICKER_DAY_MONDAY_SHORT: 'Mo', DATE_PICKER_DAY_TUESDAY_LONG: 'Dienstag', DATE_PICKER_DAY_TUESDAY_SHORT: 'Di', DATE_PICKER_DAY_WEDNESDAY_LONG: 'Mittwoch', DATE_PICKER_DAY_WEDNESDAY_SHORT: 'Mi', DATE_PICKER_DAY_THURSDAY_LONG: 'Donnerstag', DATE_PICKER_DAY_THURSDAY_SHORT: 'Do', DATE_PICKER_DAY_FRIDAY_LONG: 'Freitag', DATE_PICKER_DAY_FRIDAY_SHORT: 'Fr', DATE_PICKER_DAY_SATURDAY_LONG: 'Samstag', DATE_PICKER_DAY_SATURDAY_SHORT: 'Sa', DATE_PICKER_DAY_SUNDAY_LONG: 'Sonntag', DATE_PICKER_DAY_SUNDAY_SHORT: 'So', DISCOUNT_APPLIED: 'Rabatt eingelöst', DISCOUNT_CHECK: 'Überprüfen', DISCOUNT_TITLE: 'Rabattcode oder Gutschein', DISCOUNT_INVALID: 'Ungültiger Rabattcode oder Gutschein', ERR_AMOUNTS_NO_PACKAGE: 'Die Option "productAmounts" ist gesetzt, aber "package_id" ist nicht gesetzt', ERR_CONTACT_FORM_EMPTY: 'Das Kontaktformular ist nicht ausgefüllt', ERR_DATE_NO_SINGLE_PACKAGE: 'Die Option "date" erfordert ein einzelnes vorgefülltes Arrangement ("package_id")', ERR_DATE_PAST: 'Option "date" ist ein Datum in der Vergangenheit', ERR_GENERAL: 'Etwas ist schief gelaufen:', ERR_INVALID_DATE: 'Die Option "date" ist keine gültige ISO 8601-Datumszeichenfolge (z. B. "2019-06-28")', ERR_INVALID_ELEMENT: 'Option "Element" ist kein gültiges Element', ERR_INVALID_HOSTNAME: 'Option "recras_hostname" ist ungültig.', ERR_INVALID_LOCALE: 'Ungültiges Gebietsschema. Gültige Optionen sind: {LOCALES}', ERR_INVALID_REDIRECT_URL: 'Ungültige redirect URL. Stellen Sie sicher, dass es mit http:// or https:// beginnt', ERR_INVALID_TIME: 'Die Option "time" ist keine gültige Zeitzeichenfolge (z. B. "16:15")', ERR_NO_ELEMENT: 'Option "element" nicht eingestellt.', ERR_NO_FORM: 'Option "form_id" nicht eingestellt.', ERR_NO_HOSTNAME: 'Option "recras_hostname" nicht eingestellt.', ERR_NO_TIMES_FOR_DATE: 'Für diese Mengen sind an diesem Datum keine Zeiten mehr verfügbar. Versuchen Sie es mit einem anderen Datum.', ERR_OPTIONS_INVALID: 'Options is not a "RecrasOptions" object', GENDER_UNKNOWN: 'Unbekannte', GENDER_MALE: 'Mann', GENDER_FEMALE: 'Frau', HEADING_PRICE: 'Preis', HEADING_QUANTITY: 'Anzahl', LOADING: 'Wird geladen...', NO_PRODUCTS: 'Kein Produkt ausgewählt', PRICE_TOTAL: 'Insgesamt', PRICE_TOTAL_WITH_DISCOUNT: 'Insgesamt inklusive Rabatt', PRODUCT_MAXIMUM: '(höchstens {MAXIMUM})', PRODUCT_MINIMUM: '(mindestens {MINIMUM})', PRODUCT_REQUIRED: '{NUM} {PRODUCT} benötigt {REQUIRED_AMOUNT} {REQUIRED_PRODUCT} um auch gebucht zu werden.', TIME: 'Zeit', TIME_FORMAT: 'UU:MM', VOUCHER_ALREADY_APPLIED: 'Gutschein bereits eingelöst', VOUCHER_APPLIED: 'Gutschein eingelöst', VOUCHER_EMPTY: 'Leerer Gutscheincode', VOUCHER_QUANTITY: 'Anzahl der Gutscheine', VOUCHERS_DISCOUNT: 'Rabatt von Gutschein(en)' }, en_GB: { AGREE_ATTACHMENTS: 'I agree with the following documents:', ATTR_REQUIRED: 'Required', BOOKING_DISABLED_AGREEMENT: 'You have not agreed to the terms yet', BOOKING_DISABLED_AMOUNTS_INVALID: 'Programme amounts are invalid', BOOKING_DISABLED_CONTACT_FORM_INVALID: 'Contact form is not filled in correctly', BOOKING_DISABLED_INVALID_DATE: 'No date selected', BOOKING_DISABLED_INVALID_TIME: 'No time selected', BOOKING_DISABLED_REQUIRED_PRODUCT: 'Required product not yet selected', BUTTON_BOOK_NOW: 'Book now', BUTTON_BUY_NOW: 'Buy now', BUTTON_SUBMIT_CONTACT_FORM: 'Submit', CONTACT_FORM_CHECKBOX_REQUIRED: 'At least one option must be checked', CONTACT_FORM_FIELD_INVALID: '"{FIELD_NAME}" is invalid', CONTACT_FORM_FIELD_REQUIRED: '"{FIELD_NAME}" is a required field', CONTACT_FORM_SUBMIT_FAILED: 'The contact form could not be sent. Please try again later.', CONTACT_FORM_SUBMIT_SUCCESS: 'The contact form was sent successfully.', DATE: 'Date', DATE_FORMAT: 'DD-MM-YYYY', DATE_INVALID: 'Invalid date', DATE_PICKER_NEXT_MONTH: 'Next month', DATE_PICKER_PREVIOUS_MONTH: 'Previous month', DATE_PICKER_MONTH_JANUARY: 'January', DATE_PICKER_MONTH_FEBRUARY: 'February', DATE_PICKER_MONTH_MARCH: 'March', DATE_PICKER_MONTH_APRIL: 'April', DATE_PICKER_MONTH_MAY: 'May', DATE_PICKER_MONTH_JUNE: 'June', DATE_PICKER_MONTH_JULY: 'July', DATE_PICKER_MONTH_AUGUST: 'August', DATE_PICKER_MONTH_SEPTEMBER: 'September', DATE_PICKER_MONTH_OCTOBER: 'October', DATE_PICKER_MONTH_NOVEMBER: 'November', DATE_PICKER_MONTH_DECEMBER: 'December', DATE_PICKER_DAY_MONDAY_LONG: 'Monday', DATE_PICKER_DAY_MONDAY_SHORT: 'Mon', DATE_PICKER_DAY_TUESDAY_LONG: 'Tuesday', DATE_PICKER_DAY_TUESDAY_SHORT: 'Tue', DATE_PICKER_DAY_WEDNESDAY_LONG: 'Wednesday', DATE_PICKER_DAY_WEDNESDAY_SHORT: 'Wed', DATE_PICKER_DAY_THURSDAY_LONG: 'Thursday', DATE_PICKER_DAY_THURSDAY_SHORT: 'Thu', DATE_PICKER_DAY_FRIDAY_LONG: 'Friday', DATE_PICKER_DAY_FRIDAY_SHORT: 'Fri', DATE_PICKER_DAY_SATURDAY_LONG: 'Saturday', DATE_PICKER_DAY_SATURDAY_SHORT: 'Sat', DATE_PICKER_DAY_SUNDAY_LONG: 'Sunday', DATE_PICKER_DAY_SUNDAY_SHORT: 'Sun', DISCOUNT_APPLIED: 'Discount applied', DISCOUNT_CHECK: 'Check', DISCOUNT_TITLE: 'Discount code or voucher', DISCOUNT_INVALID: 'Invalid discount code or voucher', ERR_AMOUNTS_NO_PACKAGE: 'Option "productAmounts" is set, but "package_id" is not set', ERR_CONTACT_FORM_EMPTY: 'Contact form is not filled in', ERR_DATE_NO_SINGLE_PACKAGE: 'Option "date" requires a single pre-filled package ("package_id")', ERR_DATE_PAST: 'Option "date" is a date in the past', ERR_GENERAL: 'Something went wrong:', ERR_INVALID_DATE: 'Option "date" is not a valid ISO 8601 date string (e.g. "2019-06-28")', ERR_INVALID_ELEMENT: 'Option "element" is not a valid Element', ERR_INVALID_HOSTNAME: 'Option "recras_hostname" is invalid.', ERR_INVALID_LOCALE: 'Invalid locale. Valid options are: {LOCALES}', ERR_INVALID_REDIRECT_URL: 'Invalid redirect URL. Make sure you it starts with http:// or https://', ERR_INVALID_TIME: 'Option "time" is not a valid time string (e.g. "16:15")', ERR_NO_ELEMENT: 'Option "element" not set.', ERR_NO_FORM: 'Option "form_id" not set.', ERR_NO_HOSTNAME: 'Option "recras_hostname" not set.', ERR_NO_TIMES_FOR_DATE: 'There are no more times available on this date for these quantities. Try a different date.', ERR_OPTIONS_INVALID: 'Options is not a "RecrasOptions" object', GENDER_UNKNOWN: 'Unknown', GENDER_MALE: 'Male', GENDER_FEMALE: 'Female', HEADING_PRICE: 'Price', HEADING_QUANTITY: 'Quantity', LOADING: 'Loading...', NO_PRODUCTS: 'No product selected', PRICE_TOTAL: 'Total', PRICE_TOTAL_WITH_DISCOUNT: 'Total including discount', PRODUCT_MAXIMUM: '(at most {MAXIMUM})', PRODUCT_MINIMUM: '(at least {MINIMUM})', PRODUCT_REQUIRED: '{NUM} {PRODUCT} requires {REQUIRED_AMOUNT} {REQUIRED_PRODUCT} to also be booked.', TIME: 'Time', TIME_FORMAT: 'HH:MM', VOUCHER_ALREADY_APPLIED: 'Voucher already applied', VOUCHER_APPLIED: 'Voucher applied', VOUCHER_EMPTY: 'Empty voucher code', VOUCHER_QUANTITY: 'Number of vouchers', VOUCHERS_DISCOUNT: 'Discount from voucher(s)' }, nl_NL: { AGREE_ATTACHMENTS: 'Ik ga akkoord met de volgende gegevens:', ATTR_REQUIRED: 'Vereist', BOOKING_DISABLED_AGREEMENT: 'Je bent nog niet akkoord met de voorwaarden', BOOKING_DISABLED_AMOUNTS_INVALID: 'Aantallen in programma zijn ongeldig', BOOKING_DISABLED_CONTACT_FORM_INVALID: 'Contactformulier is niet correct ingevuld', BOOKING_DISABLED_INVALID_DATE: 'Geen datum geselecteerd', BOOKING_DISABLED_INVALID_TIME: 'Geen tijd geselecteerd', BOOKING_DISABLED_REQUIRED_PRODUCT: 'Vereist product nog niet geselecteerd', BUTTON_BOOK_NOW: 'Nu boeken', BUTTON_BUY_NOW: 'Nu kopen', BUTTON_SUBMIT_CONTACT_FORM: 'Versturen', CONTACT_FORM_CHECKBOX_REQUIRED: 'Ten minste één optie moet aangevinkt worden', CONTACT_FORM_FIELD_INVALID: '"{FIELD_NAME}" is ongeldig', CONTACT_FORM_FIELD_REQUIRED: '"{FIELD_NAME}" is een verplicht veld', CONTACT_FORM_SUBMIT_FAILED: 'Het contactformulier kon niet worden verstuurd. Probeer het later nog eens.', CONTACT_FORM_SUBMIT_SUCCESS: 'Het contactformulier is succesvol verstuurd.', DATE: 'Datum', DATE_FORMAT: 'DD-MM-JJJJ', DATE_INVALID: 'Ongeldige datum', DATE_PICKER_NEXT_MONTH: 'Volgende maand', DATE_PICKER_PREVIOUS_MONTH: 'Vorige maand', DATE_PICKER_MONTH_JANUARY: 'Januari', DATE_PICKER_MONTH_FEBRUARY: 'Februari', DATE_PICKER_MONTH_MARCH: 'Maart', DATE_PICKER_MONTH_APRIL: 'April', DATE_PICKER_MONTH_MAY: 'Mei', DATE_PICKER_MONTH_JUNE: 'Juni', DATE_PICKER_MONTH_JULY: 'Juli', DATE_PICKER_MONTH_AUGUST: 'Augustus', DATE_PICKER_MONTH_SEPTEMBER: 'September', DATE_PICKER_MONTH_OCTOBER: 'Oktober', DATE_PICKER_MONTH_NOVEMBER: 'November', DATE_PICKER_MONTH_DECEMBER: 'December', DATE_PICKER_DAY_MONDAY_LONG: 'Maandag', DATE_PICKER_DAY_MONDAY_SHORT: 'Ma', DATE_PICKER_DAY_TUESDAY_LONG: 'Dinsdag', DATE_PICKER_DAY_TUESDAY_SHORT: 'Di', DATE_PICKER_DAY_WEDNESDAY_LONG: 'Woensdag', DATE_PICKER_DAY_WEDNESDAY_SHORT: 'Wo', DATE_PICKER_DAY_THURSDAY_LONG: 'Donderdag', DATE_PICKER_DAY_THURSDAY_SHORT: 'Do', DATE_PICKER_DAY_FRIDAY_LONG: 'Vrijdag', DATE_PICKER_DAY_FRIDAY_SHORT: 'Vr', DATE_PICKER_DAY_SATURDAY_LONG: 'Zaterdag', DATE_PICKER_DAY_SATURDAY_SHORT: 'Za', DATE_PICKER_DAY_SUNDAY_LONG: 'Zondag', DATE_PICKER_DAY_SUNDAY_SHORT: 'Zo', DISCOUNT_APPLIED: 'Kortingscode toegepast', DISCOUNT_CHECK: 'Controleren', DISCOUNT_TITLE: 'Kortingscode of tegoedbon', DISCOUNT_INVALID: 'Ongeldige kortingscode of tegoedbon', ERR_AMOUNTS_NO_PACKAGE: 'Optie "productAmounts" is ingesteld, maar "package_id" is niet ingesteld', ERR_CONTACT_FORM_EMPTY: 'Contactformulier is niet ingevuld', ERR_DATE_NO_SINGLE_PACKAGE: 'Optie "date" vereist een enkel vooraf ingevuld arrangement ("package_id")', ERR_DATE_PAST: 'Optie "date" is een datum in het verleden', ERR_GENERAL: 'Er ging iets mis:', ERR_INVALID_DATE: 'Optie "date" is geen geldige ISO 8601-datumstring (bijv. "2019-06-28")', ERR_INVALID_ELEMENT: 'Optie "element" is geen geldig Element', ERR_INVALID_HOSTNAME: 'Optie "recras_hostname" is ongeldig.', ERR_INVALID_LOCALE: 'Ongeldige locale. Geldige opties zijn: {LOCALES}', ERR_INVALID_REDIRECT_URL: 'Ongeldige redirect-URL. Zorg ervoor dat deze begint met http:// of https://', ERR_INVALID_TIME: 'Optie "time" is geen geldige tijd-string (bijv. "16:15")', ERR_NO_ELEMENT: 'Optie "element" niet ingesteld.', ERR_NO_FORM: 'Optie "form_id" niet ingesteld.', ERR_NO_HOSTNAME: 'Optie "recras_hostname" niet ingesteld.', ERR_NO_TIMES_FOR_DATE: 'Er zijn geen tijden meer beschikbaar op deze datum voor deze aantallen. Probeer een andere datum.', ERR_OPTIONS_INVALID: 'Opties is geen "RecrasOptions"-object', GENDER_UNKNOWN: 'Onbekend', GENDER_MALE: 'Man', GENDER_FEMALE: 'Vrouw', HEADING_PRICE: 'Prijs', HEADING_QUANTITY: 'Aantal', LOADING: 'Laden...', NO_PRODUCTS: 'Geen product gekozen', PRICE_TOTAL: 'Totaal', PRICE_TOTAL_WITH_DISCOUNT: 'Totaal inclusief korting', PRODUCT_MAXIMUM: '(maximaal {MAXIMUM})', PRODUCT_MINIMUM: '(minimaal {MINIMUM})', PRODUCT_REQUIRED: '{NUM} {PRODUCT} vereist dat ook {REQUIRED_AMOUNT} {REQUIRED_PRODUCT} geboekt wordt.', TIME: 'Tijd', TIME_FORMAT: 'UU:MM', VOUCHER_ALREADY_APPLIED: 'Tegoedbon al toegepast', VOUCHER_APPLIED: 'Tegoedbon toegepast', VOUCHER_EMPTY: 'Lege tegoedbon', VOUCHER_QUANTITY: 'Aantal tegoedbonnen', VOUCHERS_DISCOUNT: 'Korting uit tegoedbon(nen)' }, sv_SE: { AGREE_ATTACHMENTS: 'Jag håller med följande information:', ATTR_REQUIRED: "Obligatoriskt", BOOKING_DISABLED_AGREEMENT: 'Du håller inte med villkoren ännu', BOOKING_DISABLED_AMOUNTS_INVALID: 'Siffrorna i programmet är ogiltiga', BOOKING_DISABLED_CONTACT_FORM_INVALID: 'Kontaktformuläret är inte korrekt ifyllt', BOOKING_DISABLED_INVALID_DATE: 'Inget datum valt', BOOKING_DISABLED_INVALID_TIME: 'Ingen tid vald', BOOKING_DISABLED_REQUIRED_PRODUCT: "Nödvändig produkt har ännu inte valts", BUTTON_BOOK_NOW: 'Boka nu', BUTTON_BUY_NOW: 'Köp nu', BUTTON_SUBMIT_CONTACT_FORM: 'Skicka', CONTACT_FORM_CHECKBOX_REQUIRED: 'Minst ett alternativ måste markeras', CONTACT_FORM_FIELD_INVALID: '"{FIELD_NAME}" är ogiltig', CONTACT_FORM_FIELD_REQUIRED: '"{FIELD_NAME}" är ett obligatoriskt fält', CONTACT_FORM_SUBMIT_FAILED: 'Kontaktformuläret kunde inte skickas. Vänligen försök igen senare.', CONTACT_FORM_SUBMIT_SUCCESS: 'Kontaktformuläret har skickats.', DATUM: 'Datum', DATE_FORMAT: 'DD-MM-ÅÅÅÅ', DATE_INVALID: "Ogiltigt datum", DATE_PICKER_NEXT_MONTH: "Nästa månad", DATE_PICKER_PREVIOUS_MONTH: "Förra månaden", DATE_PICKER_MONTH_JANUARI: "januari", DATE_PICKER_MONTH_FEBRUARY: "februari", DATE_PICKER_MONTH_MARCH: "mars", DATE_PICKER_MONTH_APRIL: "april", DATE_PICKER_MONTH_MAY: "aaj", DATE_PICKER_MONTH_JUNE: "juni", DATE_PICKER_MONTH_JULY: "Juli", DATE_PICKER_MONTH_AUGUST: "augusti", DATE_PICKER_MONTH_SEPTEMBER: "september", DATE_PICKER_MONTH_OCTOBER: "oktober", DATE_PICKER_MONTH_NOVEMBER: "november", DATE_PICKER_MONTH_DECEMBER: "december", DATE_PICKER_DAY_MONDAY_LONG: "Måndag", DATE_PICKER_DAY_MONDAY_SHORT: 'Mån', DATE_PICKER_DAY_TUESDAY_LONG: "Tisdag", DATE_PICKER_DAY_TUESDAY_SHORT: 'Tis', DATE_PICKER_DAY_WEDNESDAY_LONG: "Onsdag", DATE_PICKER_DAY_WEDNESDAY_SHORT: "Ons", DATE_PICKER_DAY_THURSDAY_LONG: "Torsdag", DATE_PICKER_DAY_THURSDAY_SHORT: "Tors", DATE_PICKER_DAY_FRIDAY_LONG: "Fredag", DATE_PICKER_DAY_FRIDAY_SHORT: "Fre", DATE_PICKER_DAY_SATURDAY_LONG: 'Lördag', DATE_PICKER_DAY_SATURDAY_SHORT: 'Lör', DATE_PICKER_DAY_SUNDAY_LONG: "Söndag", DATE_PICKER_DAY_SUNDAY_SHORT: "Sön", DISCOUNT_APPLIED: 'Rabattkod tillämpas', DISCOUNT_CHECK: "Kontrollera", DISCOUNT_TITLE: "Rabattkod eller kupong", DISCOUNT_INVALID: "Ogiltig rabattkod eller kupong", ERR_AMOUNTS_NO_PACKAGE: 'Alternativ "productAmounts" är inställt, men "package_id" är inte inställt', ERR_CONTACT_FORM_EMPTY: 'Kontaktformuläret är inte ifyllt', ERR_DATE_NO_SINGLE_PACKAGE: 'Alternativ "date" kräver ett enda förfyllt paket ("package_id")', ERR_DATE_PAST: 'Alternativ "date" är ett datum tidigare', ERR_GENERAL: 'Något gick fel:', ERR_INVALID_DATE: 'Alternativ "date" är inte en giltig ISO 8601-datumsträng (t.ex. "2019-06-28")', ERR_INVALID_ELEMENT: 'Alternativet "element" är inte ett giltigt element', ERR_INVALID_HOSTNAME: 'Alternativet "recras_hostname" är ogiltigt.', ERR_INVALID_LOCALE: 'Ogiltig land-språkkombination. Giltiga alternativ är: {LOCALES} ', ERR_INVALID_REDIRECT_URL: 'Ogiltig omdirigerings-URL. Se till att det börjar med http:// eller https:// ', ERR_INVALID_TIME: 'Alternativ "time" är inte en giltig tidsnotation (t.ex. "16:15")', ERR_NO_ELEMENT: 'Alternativet "element" är inte inställt.', ERR_NO_FORM: 'Alternativ "form_id" inte inställt.', ERR_NO_HOSTNAME: 'Alternativ "recras_hostname" inte inställt.', ERR_NO_TIMES_FOR_DATE: 'Det finns inga fler tillgängliga tider på detta datum för dessa nummer. Prova ett annat datum. ', ERR_OPTIONS_INVALID: 'Alternativ är inte ett "RecrasOptions"-objekt', GENDER_UNKNOWN: "Okänd", GENDER_MALE: "Man", GENDER_FEMALE: "Kvinna", HEADING_PRICE: "Pris", HEADING_QUANTITY: "Antal", LOADING: 'Laddar ...', NO_PRODUCTS: 'Ingen produkt vald', PRICE_TOTAL: 'Totalt', PRICE_TOTAL_WITH_DISCOUNT: "Totalt inklusive rabatt", PRODUCT_MAXIMUM: '(maximalt {MAXIMUM})', PRODUCT_MINIMUM: '(minimalt {MINIMUM})', PRODUCT_REQUIRED: '{NUM} {PRODUCT} kräver att {REQUIRED_AMOUNT} {REQUIRED_PRODUCT} också bokas.', TIME: 'Tid', TIME_FORMAT: 'TT:MM', VOUCHER_ALREADY_APPLIED: 'Kupongen är redan inlöst', VOUCHER_APPLIED: 'Kupong inlöst', VOUCHER_EMPTY: "Tom kupong", VOUCHER_QUANTITY: 'Antal kuponger', VOUCHERS_DISCOUNT: 'Rabatt från kupong(er)' } }; } _createClass(RecrasLanguageHelper, [{ key: "error", value: function error(msg) { console.log('Error', msg); //TODO } }, { key: "extractTags", value: function extractTags(msg) { var alphanumericWithUnderscore = '[a-zA-Z0-9_]'; var regexPartMulticolumn = '((?:\\((?:\\w+)(?::[^)]*)?\\))*)'; var regex = new RegExp('{' + alphanumericWithUnderscore + '+' + regexPartMulticolumn + '}', 'g'); var tags = msg.match(regex); if (!Array.isArray(tags)) { return []; } return tags.map(function (tag) { return tag.substring(1, tag.length - 1); }); // Strip { and } } }, { key: "filterTags", value: function filterTags(msg, packageID) { var tags = this.extractTags(msg); if (tags.length === 0) { return Promise.resolve(msg); } return RecrasHttpHelper.postJson(this.options.getApiBase() + 'tagfilter', { tags: tags, context: { packageID: packageID } }, this.error).then(function (filtered) { Object.keys(filtered).forEach(function (tag) { msg = msg.split('{' + tag + '}').join(filtered[tag]); }); return msg; }); } }, { key: "formatLocale", value: function formatLocale(what) { switch (what) { case 'currency': return this.locale.replace('_', '-').toUpperCase(); default: return this.locale; } } }, { key: "formatPrice", value: function formatPrice(price) { return parseFloat(price).toLocaleString(this.formatLocale('currency'), { currency: this.currency, style: 'currency' }); } }, { key: "setCurrency", value: function setCurrency() { var _this39 = this; var errorHandler = function errorHandler(err) { _this39.currency = 'eur'; _this39.error(err); }; return RecrasHttpHelper.fetchJson(this.options.getApiBase() + 'instellingen/currency', errorHandler).then(function (setting) { _this39.currency = setting.waarde; }); } }, { key: "setLocale", value: function setLocale(locale) { this.locale = locale; } }, { key: "setOptions", value: function setOptions(options) { this.options = options; return this.setCurrency(); } }, { key: "translate", value: function translate(string) { var vars = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var translated; if (this.i18n[this.locale] && this.i18n[this.locale][string]) { translated = this.i18n[this.locale][string]; } else if (this.i18n.en_GB[string]) { translated = this.i18n.en_GB[string]; } else { translated = string; console.warn('String not translated: ' + string); } if (Object.keys(vars).length > 0) { Object.keys(vars).forEach(function (key) { translated = translated.replace('{' + key + '}', vars[key]); }); } return translated; } }], [{ key: "isValid", value: function isValid(locale) { return this.validLocales.indexOf(locale) > -1; } }]); return RecrasLanguageHelper; }(); _defineProperty(RecrasLanguageHelper, "validLocales", ['de_DE', 'en_GB', 'nl_NL', 'sv_SE']); var RecrasOptions = /*#__PURE__*/function () { function RecrasOptions(options) { _classCallCheck(this, RecrasOptions); this.languageHelper = new RecrasLanguageHelper(); this.validate(options); this.options = this.setOptions(options); } _createClass(RecrasOptions, [{ key: "getAnalyticsEvents", value: function getAnalyticsEvents() { if (!Array.isArray(this.options.analyticsEvents)) { this.options.analyticsEvents = RecrasEventHelper.allEvents(); } this.options.analyticsEvents = this.options.analyticsEvents.filter(function (event) { var eventExists = RecrasEventHelper.allEvents().includes(event); if (!eventExists) { console.warn('Invalid event: ' + event); } return eventExists; }); if (this.options.analyticsEvents.length === 0) { this.options.analyticsEvents = RecrasEventHelper.allEvents(); } return this.options.analyticsEvents; } }, { key: "getAnalytics", value: function getAnalytics() { return this.options.analytics; } }, { key: "getApiBase", value: function getApiBase() { return this.getHostname() + '/api2/'; } }, { key: "getAutoScroll", value: function getAutoScroll() { return this.options.autoScroll !== undefined ? this.options.autoScroll : true; } }, { key: "getDefaultCountry", value: function getDefaultCountry() { if (this.options.defaultCountry !== undefined) { return this.options.defaultCountry; } return this.getLocale().substr(3, 2); // en_IE -> IE } }, { key: "getElement", value: function getElement() { return this.options.element; } }, { key: "getFormId", value: function getFormId() { return this.options.form_id; } }, { key: "getHostname", value: function getHostname() { return this.options.hostname; } }, { key: "getLocale", value: function getLocale() { return this.options.locale; } }, { key: "getPackageId", value: function getPackageId() { return this.options.package_id; } }, { key: "getPreFilledAmounts", value: function getPreFilledAmounts() { return this.options.productAmounts; } }, { key: "getPreFilledDate", value: function getPreFilledDate() { return this.options.date; } }, { key: "getPreFilledTime", value: function getPreFilledTime() { return this.options.time; } }, { key: "getPreviewTimes", value: function getPreviewTimes() { return this.options.previewTimes !== undefined ? this.options.previewTimes : true; } }, { key: "getRedirectUrl", value: function getRedirectUrl() { return this.options.redirect_url; } }, { key: "getVoucherTemplateId", value: function getVoucherTemplateId() { return this.options.voucher_template_id; } }, { key: "isSinglePackage", value: function isSinglePackage() { if (Array.isArray(this.options.package_id)) { return this.options.package_id.length === 1; } return !isNaN(parseInt(this.options.package_id, 10)); } }, { key: "setOption", value: function setOption(option, value) { this.options[option] = value; } }, { key: "setOptions", value: function setOptions(options) { var protocol = 'https'; if (RecrasOptions.hostnamesDebug.includes(options.recras_hostname)) { protocol = 'http'; } options.hostname = protocol + '://' + options.recras_hostname; return options; } }, { key: "validate", value: function validate(options) { var hostnameRegex = new RegExp(/^[a-z0-9\-]+\.recras\.nl$/i); if (!options.element) { throw new Error(this.languageHelper.translate('ERR_NO_ELEMENT')); } if (options.element instanceof Element === false) { throw new Error(this.languageHelper.translate('ERR_INVALID_ELEMENT')); } if (!options.recras_hostname) { throw new Error(this.languageHelper.translate('ERR_NO_HOSTNAME')); } if (!hostnameRegex.test(options.recras_hostname) && !RecrasOptions.hostnamesDebug.includes(options.recras_hostname)) { throw new Error(this.languageHelper.translate('ERR_INVALID_HOSTNAME')); } if (options.redirect_url) { if (options.redirect_url.indexOf('http://') === -1 && options.redirect_url.indexOf('https://') === -1) { throw new Error(this.languageHelper.translate('ERR_INVALID_REDIRECT_URL')); } } } }]); return RecrasOptions; }(); _defineProperty(RecrasOptions, "hostnamesDebug", ['nginx:8886', // Local development 'nginx' // Docker Selenium tests ]); var RecrasVoucher = /*#__PURE__*/function () { function RecrasVoucher() { var _this40 = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, RecrasVoucher); this.languageHelper = new RecrasLanguageHelper(); if (options instanceof RecrasOptions === false) { throw new Error(this.languageHelper.translate('ERR_OPTIONS_INVALID')); } this.options = options; this.eventHelper = new RecrasEventHelper(); this.eventHelper.setEvents(this.options.getAnalyticsEvents()); this.element = this.options.getElement(); this.element.classList.add('recras-buy-voucher'); this.fetchJson = function (url) { return RecrasHttpHelper.fetchJson(url, _this40.error); }; this.postJson = function (url, data) { return RecrasHttpHelper.postJson(_this40.options.getApiBase() + url, data, _this40.error); }; RecrasCSSHelper.loadCSS('global'); if (this.options.getLocale()) { if (!RecrasLanguageHelper.isValid(this.options.getLocale())) { console.warn(this.languageHelper.translate('ERR_INVALID_LOCALE', { LOCALES: RecrasLanguageHelper.validLocales.join(', ') })); } else { this.languageHelper.setLocale(this.options.getLocale()); } } this.languageHelper.setOptions(options).then(function () { return _this40.getVoucherTemplates(); }).then(function (templates) { if (_this40.options.getVoucherTemplateId()) { _this40.changeTemplate(_this40.options.getVoucherTemplateId()); } else { _this40.showTemplates(templates); } }); } _createClass(RecrasVoucher, [{ key: "appendHtml", value: function appendHtml(msg) { this.element.insertAdjacentHTML('beforeend', msg); } }, { key: "buyTemplate", value: function buyTemplate() { var _this41 = this; var status = this.contactForm.checkRequiredCheckboxes(); if (!status) { return false; } this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_VOUCHER, RecrasEventHelper.EVENT_VOUCHER_VOUCHER_SUBMITTED, this.selectedTemplate.name, Math.round(this.totalPrice())); this.findElement('.buyTemplate').setAttribute('disabled', 'disabled'); var payload = { voucher_template_id: this.selectedTemplate.id, number_of_vouchers: parseInt(this.findElement('.number-of-vouchers').value, 10), contact_form: this.contactForm.generateJson() }; if (this.options.getRedirectUrl()) { payload.redirect_url = this.options.getRedirectUrl(); } this.postJson('vouchers/buy', payload).then(function (json) { if (json.payment_url) { _this41.eventHelper.sendEvent(RecrasEventHelper.PREFIX_VOUCHER, RecrasEventHelper.EVENT_VOUCHER_REDIRECT_PAYMENT, null, Math.round(_this41.totalPrice())); window.top.location.href = json.payment_url; } else { console.log(json); } _this41.findElement('.buyTemplate').removeAttribute('disabled'); }); } }, { key: "changeTemplate", value: function changeTemplate(templateID) { this.selectedTemplate = this.templates.filter(function (t) { return t.id === templateID; })[0]; this.clearAllExceptTemplateSelection(); this.showContactForm(this.selectedTemplate); this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_VOUCHER, RecrasEventHelper.EVENT_VOUCHER_TEMPLATE_CHANGED, null, templateID); } }, { key: "clearAll", value: function clearAll() { this.clearElements(this.element.children); } }, { key: "clearAllExceptTemplateSelection", value: function clearAllExceptTemplateSelection() { var elements = document.querySelectorAll('#' + this.element.id + ' > *:not(.recras-voucher-templates)'); this.clearElements(elements); } }, { key: "clearElements", value: function clearElements(elements) { _toConsumableArray(elements).forEach(function (el) { el.parentNode.removeChild(el); }); this.maybeAddLatestErrorElement(); } }, { key: "error", value: function error(msg) { this.maybeAddLatestErrorElement(); this.findElement('.latestError').innerHTML = "".concat(this.languageHelper.translate('ERR_GENERAL'), "").concat(msg, "
"); } }, { key: "findElement", value: function findElement(querystring) { return this.element.querySelector(querystring); } }, { key: "findElements", value: function findElements(querystring) { return this.element.querySelectorAll(querystring); } }, { key: "formatPrice", value: function formatPrice(price) { return this.languageHelper.formatPrice(price); } }, { key: "getContactForm", value: function getContactForm(template) { var _this42 = this; this.options.setOption('form_id', template.contactform_id); var contactForm = new RecrasContactForm(this.options); return contactForm.getContactFormFields().then(function () { _this42.contactForm = contactForm; return contactForm; }); } }, { key: "getVoucherTemplates", value: function getVoucherTemplates() { var _this43 = this; return this.fetchJson(this.options.getApiBase() + 'voucher_templates').then(function (templates) { templates = templates.filter(function (template) { return !!template.contactform_id; }); _this43.templates = templates; return templates; }); } }, { key: "maybeAddLatestErrorElement", value: function maybeAddLatestErrorElement() { var errorEl = this.findElement('.latestError'); if (!errorEl) { this.appendHtml(""); } } }, { key: "maybeDisableBuyButton", value: function maybeDisableBuyButton() { var button = this.findElement('.buyTemplate'); if (!button) { return false; } var shouldDisable = false; this.contactForm.removeErrors(); if (this.contactForm.hasEmptyRequiredFields() || !this.contactForm.isValid() || !this.contactForm.checkRequiredCheckboxes()) { this.contactForm.showInlineErrors(); shouldDisable = true; } if (shouldDisable) { button.setAttribute('disabled', 'disabled'); } else { button.removeAttribute('disabled'); } } }, { key: "showBuyButton", value: function showBuyButton() { var html = ""); this.appendHtml(html); this.findElement('.buyTemplate').addEventListener('click', this.buyTemplate.bind(this)); } }, { key: "showContactForm", value: function showContactForm(template) { var _this44 = this; return this.getContactForm(template).then(function (form) { return form.generateForm({ voucherQuantitySelector: true, quantityTerm: _this44.selectedTemplate.quantity_term }); }).then(function (html) { _this44.appendHtml(html); _this44.showBuyButton(); _toConsumableArray(_this44.findElements('#number-of-vouchers, [name^="contactformulier"]')).forEach(function (el) { el.addEventListener('change', _this44.maybeDisableBuyButton.bind(_this44)); }); }); } }, { key: "showTemplates", value: function showTemplates(templates) { var _this45 = this; var templateOptions = templates.map(function (template) { return "